#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
using namespace std;

class Thread
{
public:
    typedef enum
    {
        NEW = 0,
        RUNNING,
        EXIT
    } ThreadStatus;
    typedef void (*func_t)(void *); // 线程要执行的函数，并不一定是入口函数，而是让线程的入口函数回调func_t这个函数

public:
    Thread(int num = 0, func_t func = nullptr, void *args = nullptr)
        : _func(func),
          _args(args),
          _status(NEW)
    {
        char name[64];
        snprintf(name, 64, "thread-%d", num);
        _name = name;
    }

    ~Thread()
    {
    }
    string getStatus()
    {
        switch (_status)
        {
        case 0:
            return "NEW";
        case 1:
            return "RUNNING";
        case 2:
            return "EXIT";
        }
    }

    string getName()
    {
        return _name;
    }

    pthread_t getPid()
    {
        if (_status == RUNNING)
            return _tid;
        else
            return 0;
    }

    // 类内的成员函数默认第一个参数是this指针，因此必须要设置成静态成员函数，pthread_create才能匹配参数
    // 当入口函数变为静态成员函数时，是无法访问类内的成员函数的，因此要传入this指针

    static void *runHelpter(void *args) // 线程的入口函数，进行回调_func --> 把执行的函数喂给类，让类进行回调
    {
        Thread *ts = static_cast<Thread *>(args);
        (*ts)();
    }

    void operator()() // 仿函数，进行回调_func
    {
        if (_func != nullptr)
            _func(_args);
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        if (n != 0)
        {
            cerr << "man thread join " << _name << "error" << endl;
            return;
        }
        _status = EXIT;
    }
    // 让线程跑起来
    void run()
    {
        int n = pthread_create(&_tid, nullptr, runHelpter, this);
        if (n != 0)
            exit(-1);
        _status = RUNNING;
    }

private:
    pthread_t _tid;       // 线程id
    string _name;         // 线程的名字
    void *_args;          // 传给回调函数_func的参数
    func_t _func;         // 线程要执行的函数,并不一定是入口函数
    ThreadStatus _status; // 线程的状态
};